#!user/bin/env python3
# -- coding: utf-8 --
# 1.局部变量
import functools


def num():
    a = 123
    print(a)


# num()
# print(a)  # 无法撒调用，会报错
# 2.全局变量
a = 234


def nnm():
    print(a)


# nnm()
# print(a)  # 可以调用
# 3、在函数内部修改全局变量   （ global ）
# 切记：不要轻易修改全局变量，除非万不得已！！！
a = 520


def num():
    global a  # a是全局变量
    a = 510  # 对变量a重新赋值
    print(a)


# num()
# 4.多函数程序执行流程：一般在实际开发过程中，一个程序往往由多个函数组成，并且多个函数共享某些数据。
"""
多函数共用全局变量的流程：
1、声明全局变量
2、定义两个函数
3、函数1修改全局变量，函数2访问全局变量
4、先调用函数1（函数1修改了全局变量），再调用函数2时就可以使用修改后的全局变量了
"""
a = 520


def num1():
    global a
    a = 510


def num2():
    print(a)


num1()
num2()


def 函数名(a, b):  # 定义函数，设两个形参，a和b
    return a + b  # return 返回a+b的值，退出当前函数\
    # 如果这里有多条return语句只执行第1个
    # 遇到return退出当前函数
    # 多个返回值写成 return a,b    返回是一个元组（a,b）
    # return后面可以连接列表，元组或字典，也能返回多个返回值


变量名 = 函数名(520, 1314)  # 用变量名保存函数的返回值
print(变量名)  # 打印变量名

# 多函数程序执行流程：一般在实际开发过程中，一个程序往往由多个函数组成，并且多个函数共享某些数据。
"""
多函数返回值做参数传递：
1、定义函数1，return返回一个值
2、定义带形参的函数2，打印形参
3、将调用函数1的返回值，赋值给一个变量。例如： 变量名 = 函数名1( )
4、调用函数2，用刚才的变量做参数。 例如：函数名2(变量名)
"""


def word1():
    return '我是中国人'


def word2(a):
    print(a)


b = word1()
word2(b)


# 元组拆包
def 函数名():
    return 520, 1314


a, b = 函数名()
print(a)
print(b)

# 字典拆包
字典 = {'姓名': '张三', '年龄': 20}


def dicts():
    return 字典


a, b = dicts()

# 对字典拆包取来的是字典的“键”
print(a)  # 姓名
print(b)  # 年龄

print(字典[a])  # 张三
print(字典[b])  # 20

sum = 0
for i in range(101):
    sum = sum + i
print(sum)


# 递归
def add(num):
    if num == 1:
        return 1  # 设置出口
    sum = num + add(num - 1)  # 一直循环调用add()函数
    return sum


a = add(98)
print(a)


# lambda表达式
# lambda 形参:表达式
def a():
    return 520


# print(a())
a = (lambda: 520)()  # 无参数
print(a)


def add(a, b):
    return a + b


print(add(1, 10))
add = (lambda a, b: a + b)(2, 6)  # 两个参数

print(add)


def add(num):
    return '我是张三'


print(add(2))
acc = (lambda num: '我是张三')(2)  # 一个实参
print(acc)


def add(a, b, c=6):
    return a + b - c


print(add(2, 5))
acc = (lambda a, b, c=6: a + b - c)(2, 5)  # 默认参数
print(acc)
acc = (lambda *args: args)(1, 1, 2, 3, 1)  # 可变位置参数，返回一个元组
print(acc)
acc = (lambda **kwargs: kwargs)(nmae='张三', age=24)  # 可变关键字参数，返回一个字典
print(acc)


# 带条件语句的lambda函数
def re(a, b):
    return a if a > b else b  # a和b比较，如果a>b,返回a；否则返回b。


word = re(2, 6)
print(word)
word = (lambda a, b: a if a > b else b)(2, 6)
print(word)


# filter是筛选，filter(函数名，可迭代对象)，需要list转换
def num(x):
    return x % 2 == 0


a = list(filter(num, range(1, 11)))
print(a)

a = list(filter(lambda x: x % 2 == 0, range(1, 11)))
print(a)


# map函数，map(函数名，可迭代对象),将每一个可迭代对象的元素作为实参进行运算
def num(x):
    return x ** 3


a = list(map(num, range(1, 11)))
print(a)
a = list(map(lambda x: x ** 3, range(1, 11)))
print(a)


# functools.reduce()函数 ，reduce(函数名，可迭代对象)
# 作用：函数中必须有两个参数，每次函数计算的结果继续和序列的下一个元素做累计计算
def add(a, b):
    return a + b


a = functools.reduce(add, range(1, 101))
print(a)
a = functools.reduce(lambda a, b: a + b, range(1, 101))
print(a)
